home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / DEMON / RISCOS2 / TCP_131S.ARC / c / AX25 < prev    next >
Text File  |  1994-03-05  |  14KB  |  380 lines

  1. /* Low level AX.25 frame processing - address header */
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <ctype.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "iface.h"
  10. #include "timer.h"
  11. #include "arp.h"
  12. #include "slip.h"
  13. #include "ax25.h"
  14. #include "lapb.h"
  15. #include "netrom.h"
  16. #include "ip.h"
  17.  
  18. /* AX.25 broadcast address: "QST-0" in shifted ascii */
  19. struct ax25_addr ax25_bdcst = {
  20.         'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1,
  21.         ('0'<<1) | E,
  22. };
  23. char axbdcst[AXALEN];   /* Same thing, network format */
  24. struct ax25_addr mycall;
  25. int digipeat = 1;       /* Controls digipeating */
  26. int32 digisent = 0;     /* Number of digipeated packets */
  27. struct ax25mh mhlist[40];       /* mheard list - 40 entries */
  28.  
  29. /* Send IP datagrams across an AX.25 link */
  30. int ax_send(struct mbuf *bp, struct interface *interface, int32 gateway, 
  31.             char precedence, char delay, char throughput, char reliability)
  32. {
  33.         char *hw_addr;
  34.         struct ax25_cb *axp;
  35.         struct ax25 addr;
  36.         struct ax25_addr destaddr;
  37.         struct mbuf *tbp,*bptmp;
  38.         extern int16 axwindow;
  39.         int16 ssize,len,size;
  40.         int segments,first;
  41.  
  42.         throughput = throughput;
  43.         precedence = precedence;
  44.  
  45.         if((hw_addr = res_arp(interface,ARP_AX25,gateway,bp)) == NULLCHAR)
  46.                 return 0;       /* Wait for address resolution */
  47.  
  48.         if(delay || (!reliability && (interface->flags == DATAGRAM_MODE))){
  49.                 /* Use UI frame */
  50.                 return (*interface->output)(interface,hw_addr,interface->hwaddr,PID_IP,bp);
  51.         }
  52.         /* Reliability is needed; use I-frames in AX.25 connection */
  53.         memcpy(destaddr.call,hw_addr,ALEN);
  54.         destaddr.ssid = hw_addr[ALEN];
  55.  
  56.         if((axp = find_ax25(&destaddr)) == NULLAX25)
  57.         {
  58.                 /* Open a new connection */
  59.                 atohax25(&addr,hw_addr,(struct ax25_addr *)interface->hwaddr);
  60.                 axp = open_ax25(&addr,axwindow,(void (*)())ax_incom,NULLVFP,NULLVFP,interface,(char *)0);
  61.                 if(axp == NULLAX25)
  62.                 {
  63.                         free_p(bp);
  64.                         return -1;
  65.                 }
  66.         }
  67.  
  68.         /* New-style frame segmenter. Returns queue of segmented fragments,
  69.          * or original packet if small enough
  70.          * See if packet is too small to segment. Note 1-byte grace factor
  71.          * so the PID will not cause segmentation of a 256-byte IP datagram.
  72.          */
  73.         len   = len_mbuf(bp);
  74.         ssize = axp->paclen;
  75.  
  76.         if((bptmp = alloc_mbuf(len+1)) == NULLBUF)
  77.         {
  78.                 free_p(bp);
  79.                 return -1;
  80.         }
  81.         bptmp->data[0] = PID_IP;
  82.         bptmp->cnt = 1;
  83.         bptmp->cnt += pullup(&bp,bptmp->data+1,len);
  84.  
  85.         if(len <= ssize + 1)
  86.         {     /* Too small to segment */
  87.                 send_ax25(axp,bptmp);
  88.                 return 0;
  89.         }
  90.  
  91.         len = len_mbuf(bptmp);
  92.         ssize -= 2;             /* ssize now equal to data portion size */
  93.         segments = 1 + (len - 1) / ssize;       /* # segments */
  94.         first = 1;
  95.  
  96.         while(segments != 0){
  97.                 size = min(ssize,len_mbuf(bptmp));
  98.                 if((tbp = alloc_mbuf(size + 2)) == NULLBUF)
  99.                         break;
  100.                 tbp->data[0] = PID_SEGMENT;
  101.                 tbp->data[1] = --segments;
  102.                 if(first){
  103.                         tbp->data[1] |= SEG_FIRST;
  104.                         first = 0;
  105.                 }
  106.                 tbp->cnt = 2;
  107.                 tbp->cnt += pullup(&bptmp,tbp->data+2,size);
  108.                 send_ax25(axp,tbp);
  109.         }
  110.  
  111.         return 0;
  112. }
  113. /* Add AX.25 link header and send packet.
  114.  * Note that the calling order here must match ec_output
  115.  * since ARP also uses it.
  116.  */
  117. int ax_output(struct interface *interface, char *dest, char *source, 
  118.               char pid, struct mbuf *data)
  119. {
  120.         struct mbuf *abp,*cbp;
  121.         struct ax25 addr;
  122.         
  123.         /* Allocate mbuf for control and PID fields, and fill in */
  124.         if((cbp = pushdown(data,2)) == NULLBUF)
  125.         {
  126.                 free_p(data);
  127.                 return -1;
  128.         }
  129.         cbp->data[0] = UI;
  130.         cbp->data[1] = pid;
  131.  
  132.         atohax25(&addr,dest,(struct ax25_addr *)source);
  133.         if((abp = htonax25(&addr,cbp)) == NULLBUF)
  134.         {
  135.                 free_p(cbp);    /* Also frees data */
  136.                 return -1;
  137.         }
  138.         /* This shouldn't be necessary because redirection has already been
  139.          * done at the IP router layer, but just to be safe...
  140.          */
  141.         if(interface->forw != NULLIF)
  142.                 return (*interface->forw->raw)(interface->forw,abp);
  143.         else
  144.                 return (*interface->raw)(interface,abp);
  145. }
  146. /* Process incoming AX.25 packets.
  147.  * After optional tracing, the address field is examined. If it is
  148.  * directed to us as a digipeater, repeat it.  If it is addressed to
  149.  * us or to QST-0, kick it upstairs depending on the protocol ID.
  150.  */
  151. void ax_recv(struct interface *interface, struct mbuf *bp)
  152. {
  153.         struct ax25_addr *ap;
  154.         struct mbuf *hbp;
  155.         char multicast;
  156.         int nrnodes = 0;
  157.         int mheard_entry, mheard_work;
  158.         struct ax25_addr mhcall;
  159.         time_t mheard_oldest;
  160.         char control;
  161.         struct ax25 hdr;
  162.         struct ax25_cb *axp;
  163.         struct ax25_addr ifcall;
  164.         extern struct ax25_addr nr_nodebc ;
  165.  
  166.         /* Use the address associated with this interface */
  167.         memcpy(ifcall.call,interface->hwaddr,ALEN);
  168.         ifcall.ssid = interface->hwaddr[ALEN];
  169.  
  170.         /* Pull header off packet and convert to host structure */
  171.         if(ntohax25(&hdr,&bp) < 0)
  172.         {
  173.                 /* Something wrong with the header */
  174.                 free_p(bp);
  175.                 return;
  176.         }
  177.  
  178.         /* mheard capture code lives here */
  179.         mheard_entry = 0;       /* start at the top of the list */
  180.         mheard_work = 0;        /* used for spotting oldest entry */
  181.         time(&mheard_oldest);   /* preload very new! */
  182.         memcpy(&mhcall,&hdr.source,sizeof(struct ax25_addr));
  183.         mhcall.ssid &= SSID; /* remove junk */
  184.  
  185.         for (mheard_work = 0; mheard_work < 40 ;mheard_work++)
  186.                 {
  187.                 if(memcmp(&mhlist[mheard_work].mheard_call,&mhcall,
  188.                                                 sizeof(struct ax25_addr)) == 0)
  189.                         {
  190.                         mheard_entry = mheard_work;     /* existing entry */
  191.                         break;  /* exit and update entry */
  192.                         }
  193.                 else
  194.                         {
  195.                         if(mhlist[mheard_work].mheard_time < mheard_oldest)
  196.                                 {
  197.                                 mheard_entry = mheard_work; /* oldest so far */
  198.                                 mheard_oldest = mhlist[mheard_work].mheard_time;
  199.                                 }
  200.                         }
  201.                 }               /* loop until all parsed */
  202.  
  203.         memcpy(&mhlist[mheard_entry].mheard_call,&mhcall,
  204.                 sizeof(struct ax25_addr));              /* callsign */
  205.  
  206.         if(hdr.ndigis > 0)
  207.                 {
  208.                 if(hdr.digis[0].ssid & REPEATED)
  209.                         mhlist[mheard_entry].mheard_digi = 1;   /* repeated */
  210.                 }
  211.         else
  212.                 {
  213.                 mhlist[mheard_entry].mheard_digi = 0;   /* directly */
  214.                 }
  215.  
  216.         time(&mhlist[mheard_entry].mheard_time);                /* capture time */
  217.  
  218.         /* end of mheard capture code */
  219.  
  220.         /* Scan, looking for our call in the repeater fields, if any.
  221.          * Repeat appropriate packets.
  222.          */
  223.         for(ap = &hdr.digis[0]; ap < &hdr.digis[hdr.ndigis]; ap++){
  224.                 if(ap->ssid & REPEATED)
  225.                         continue;       /* Already repeated */
  226.                 /* Check if packet is directed to us as a digipeater */
  227.                 if(digipeat && addreq(ap,&ifcall)){
  228.                         /* Yes, kick it back out */
  229.                         ap->ssid |= REPEATED;
  230.                         if((hbp = htonax25(&hdr,bp)) != NULLBUF){
  231.                                 if(interface->forw != NULLIF)
  232.                                         (*interface->forw->raw)(interface->forw,hbp);
  233.                                 else
  234.                                         (*interface->raw)(interface,hbp);
  235.                                 bp = NULLBUF;
  236.                                 digisent++;
  237.                         }
  238.                 }
  239.                 free_p(bp);     /* Dispose if not forwarded */
  240.                 return;
  241.         }
  242.         /* Packet has passed all repeaters, now look at destination */
  243.         if(addreq(&hdr.dest,&ax25_bdcst)){
  244.                 multicast = 1;  /* Broadcast packet */
  245.         } else if(addreq(&hdr.dest,&ifcall)){
  246.                 multicast = 0;  /* Packet directed at us */
  247.         } else if(addreq(&hdr.dest,&nr_nodebc)){
  248.                 nrnodes = 1 ;
  249.         } else {
  250.                 /* Not for us */
  251.                 free_p(bp);
  252.                 return;
  253.         }
  254.         if(bp == NULLBUF){
  255.                 /* Nothing left */
  256.                 return;
  257.         }
  258.         /* Sneak a peek at the control field. This kludge is necessary because
  259.          * AX.25 lacks a proper protocol ID field between the address and LAPB
  260.          * sublayers; a control value of UI indicates that LAPB is to be
  261.          * bypassed.
  262.          */
  263.         control = *bp->data & ~PF;
  264.         if(uchar(control) == UI){
  265.                 char pid;
  266.  
  267.                 pullchar(&bp);
  268.                 if(pullone(&bp,&pid) != 1)
  269.                         return;         /* No PID */
  270.                 /* NET/ROM is very poorly layered. The meaning of the stuff
  271.                  * following the PID of CF depends on what's in the AX.25 dest
  272.                  * field.
  273.                  */
  274.                 if(nrnodes){
  275.                         if(uchar(pid) == PID_NETROM)
  276.                                 nr_nodercv(interface,&hdr.source,bp) ;
  277.                         else    /* regular UI packets to "nodes" aren't for us */
  278.                                 free_p(bp) ;
  279.                         return ;
  280.                 }
  281.                 /* Handle packets. Multi-frame messages are not allowed */
  282.                 switch(pid){
  283.                 case PID_IP:
  284.                         ip_route(bp,multicast);
  285.                         break;
  286.                 case PID_ARP:
  287.                         arp_input(interface,bp);
  288.                         break;
  289.                 default:
  290.                         free_p(bp);
  291.                         break;
  292.                 }
  293.                 return;
  294.         }
  295.  
  296.         /* Everything from here down is LAPB stuff, so drop anything
  297.          * not directed to us:
  298.          */
  299.  
  300.         if (multicast || nrnodes) {
  301.                 free_p(bp) ;
  302.                 return ;
  303.         }
  304.                 
  305.         /* Find the source address in hash table */
  306.         if((axp = find_ax25(&hdr.source)) == NULLAX25){
  307.                 /* Create a new ax25 entry for this guy,
  308.                  * insert into hash table keyed on his address,
  309.                  * and initialize table entries
  310.                  */
  311.                 if((axp = cr_ax25(&hdr.source)) == NULLAX25){
  312.                         free_p(bp);
  313.                         return;
  314.                 }
  315.                 axp->interface = interface;
  316.                 /* Swap source and destination, reverse digi string */
  317.                 axp->addr.dest = hdr.source;
  318.                 axp->addr.source = hdr.dest;
  319.                 if(hdr.ndigis > 0){
  320.                         int i,j;
  321.  
  322.                         /* Construct reverse digipeater path */
  323.                         for(i=hdr.ndigis-1,j=0;i >= 0;i--,j++){
  324.                                 axp->addr.digis[j] = hdr.digis[i];
  325.                                 axp->addr.digis[j].ssid &= ~(E|REPEATED);
  326.                         }
  327.                         /* Scale timers to account for extra delay */
  328.                         axp->t1.start *= hdr.ndigis+1;
  329.                         axp->t2.start *= hdr.ndigis+1;
  330.                         axp->t3.start *= hdr.ndigis+1;
  331.                 }
  332.                 axp->addr.ndigis = hdr.ndigis;
  333.         }
  334.         if(hdr.cmdrsp == UNKNOWN)
  335.                 axp->proto = V1;        /* Old protocol in use */
  336.         else
  337.                 axp->proto = V2;
  338.  
  339.         lapb_input(axp,hdr.cmdrsp,bp);
  340. }
  341. /* Initialize AX.25 entry in arp device table */
  342. /* General purpose AX.25 frame output */
  343. int sendframe(struct ax25_cb *axp, char cmdrsp, char ctl, 
  344.               struct mbuf *data)
  345. {
  346.         struct mbuf *hbp,*cbp;
  347.         int i;
  348.  
  349.         if(axp == NULLAX25 || axp->interface == NULLIF)
  350.                 return -1;
  351.  
  352.         /* Add control field */
  353.         if((cbp = pushdown(data,1)) == NULLBUF){
  354.                 free_p(data);
  355.                 return -1;
  356.         }
  357.         cbp->data[0] = ctl;
  358.  
  359.         axp->addr.cmdrsp = cmdrsp;
  360.         /* Create address header */
  361.         if((hbp = htonax25(&axp->addr,cbp)) == NULLBUF){
  362.                 free_p(cbp);
  363.                 return -1;
  364.         }
  365.         /* The packet is all ready, now send it */
  366.         if(axp->interface->forw != NULLIF)
  367.                 i = (*axp->interface->forw->raw)(axp->interface->forw,hbp);
  368.         else
  369.                 i = (*axp->interface->raw)(axp->interface,hbp);
  370.  
  371.         return i;
  372. }
  373. void axarp(void)
  374. {
  375.         memcpy(axbdcst,ax25_bdcst.call,ALEN);
  376.         axbdcst[ALEN] = ax25_bdcst.ssid;
  377.  
  378.         arp_init(ARP_AX25,AXALEN,PID_IP,PID_ARP,axbdcst,psax25,setpath);
  379. }
  380.